<?php
/**
 * YImage.php
 *
 * @author Hua Yang <htmlcook@gmail.com>
 * @since 2.0
 */

Yii::import('common.components.image.gd.YGdImagine');

/**
 * Class YImage
 */
class YImage extends CApplicationComponent
{
	private $_imagine;

	public function load($path)
	{
		if (!isset($this->_imagine)) {
			$this->_imagine = new YGdImagine();
		}

		return $this->_imagine->open($path);
	}

	public function watermark($filePath, $watermarkFilePath, array $position = array())
	{
		$sourceImagine = new YGdImagine();
		$watermarkImagine = new YGdImagine();
		$img = $sourceImagine->open($filePath);
		$watermark = $watermarkImagine->open($watermarkFilePath);
		$img->paste($watermark, $position);
		return $img;
	}

	public function constrainDimensions($currentWidth, $currentHeight, $maxWidth = 0, $maxHeight = 0)
	{
		if (!$maxWidth and !$maxHeight)
			return array($currentWidth, $currentHeight);

		$widthRatio = $heightRatio = 1.0;
		$didWidth = $didHeight = false;

		if ($maxWidth > 0 && $currentWidth > 0 && $currentWidth > $maxWidth) {
			$widthRatio = $maxWidth / $currentWidth;
			$didWidth = true;
		}

		if ($maxHeight > 0 && $currentHeight > 0 && $currentHeight > $maxHeight) {
			$heightRatio = $maxHeight / $currentHeight;
			$didHeight = true;
		}

		// Calculate the larger/smaller ratios
		$smallerRatio = min($widthRatio, $heightRatio);
		$largerRatio = max($widthRatio, $heightRatio);

		if (intval($currentWidth * $largerRatio) > $maxWidth || intval($currentHeight * $largerRatio) > $maxHeight)
			// The larger ratio is too big. It would result in an overflow.
			$ratio = $smallerRatio;
		else
			// The larger ratio fits, and is likely to be a more "snug" fit.
			$ratio = $largerRatio;

		// Very small dimensions may result in 0, 1 should be the minimum.
		$w = max(1, intval($currentWidth * $ratio));
		$h = max(1, intval($currentHeight * $ratio));

		// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
		// We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
		// Thus we look for dimensions that are one pixel shy of the max value and bump them up
		if ($didWidth && $w == $maxWidth - 1)
			$w = $maxWidth; // Round it up
		if ($didHeight && $h == $maxHeight - 1)
			$h = $maxHeight; // Round it up

		return array($w, $h);
	}
}